
'use strict';

const ref = require('ref-napi');
const StructType = require('ref-struct-napi');
const ArrayType = require('ref-array-napi');

/**
 * common data types and definitions
 */
const typedef = module.exports = {};

typedef.Ref = ref;
typedef.Struct = StructType;
typedef.Array = ArrayType;

/**
 * data types
 */

/**
 * basic types
 */

typedef.MLong = ref.types.long;
typedef.UMLong = ref.types.uint32;
typedef.MFloat = ref.types.float;
typedef.MDouble = ref.types.double;
typedef.MByte = ref.types.uchar;
typedef.MWord = ref.types.ushort;
typedef.MDWord = ref.types.uint;
typedef.MHandle = ref.refType(ref.types.void);
typedef.MChar = ref.types.char;
typedef.MBool = ref.types.long;
typedef.MVoid = ref.types.void;
typedef.MPVoid = ref.refType(ref.types.void);
typedef.MPChar = ref.types.CString;
typedef.MShort = ref.types.short;
typedef.MPCChar = ref.types.CString;

typedef.MRESULT = typedef.MLong;
typedef.MCOLORREF = typedef.MDWord;

typedef.MInt8 = ref.types.int8;
typedef.MUInt8 = ref.types.uint8;
typedef.MInt16 = ref.types.int16;
typedef.MUInt16 = ref.types.uint16;
typedef.MInt32 = ref.types.int32;
typedef.MUInt32 = ref.types.uint32;
typedef.MInt64 = ref.types.long;
typedef.MUInt64 = ref.types.long;

/**
 * ASVLOFFSCREEN
 */

typedef.__tag_rect = StructType({
  left: typedef.MInt32,
  top: typedef.MInt32,
  right: typedef.MInt32,
  bottom: typedef.MInt32
});
typedef.MRECT = typedef.__tag_rect;
typedef.PMRECT = ref.refType(typedef.__tag_rect);

typedef.__tag_point = StructType({
  x: typedef.MInt32,
  y: typedef.MInt32
});
typedef.MPOINT = typedef.__tag_point;
typedef.PMPOINT = ref.refType(typedef.__tag_point);



//typedef struct __tag_ASVL_OFFSCREEN
// {
// 	MUInt32	u32PixelArrayFormat;
// 	MInt32	i32Width;
// 	MInt32	i32Height;
// 	MUInt8*	ppu8Plane[4];
// 	MInt32	pi32Pitch[4];
// }ASVLOFFSCREEN, *LPASVLOFFSCREEN;

typedef.__tag_ASVL_OFFSCREEN = StructType({
  u32PixelArrayFormat: typedef.MUInt32,
  i32Width: typedef.MInt32,
  i32Height: typedef.MInt32,
  ppu8Plane: ArrayType(ref.refType(typedef.MUInt8), 4),
  pi32Pitch: ArrayType(typedef.MInt32, 4)
});
typedef.ASVLOFFSCREEN = typedef.__tag_ASVL_OFFSCREEN;
typedef.LPASVLOFFSCREEN = ref.refType(typedef.__tag_ASVL_OFFSCREEN);

typedef.__tag_ASVL_VERSION = StructType({
  lCodebase: typedef.MLong,
  lMajor: typedef.MLong,
  lMinor: typedef.MLong,
  lBuild: typedef.MLong,
  Version: typedef.MPCChar,
  BuildDate: typedef.MPCChar,
  CopyRight: typedef.MPCChar
});
typedef.ASVL_VERSION = typedef.__tag_ASVL_VERSION;


// 检测模式,并枚举检测模式
typedef.ASF_DETECT_MODE_VIDEO = 0x00000000;		//Video模式，一般用于多帧连续检测
typedef.ASF_DETECT_MODE_IMAGE = 0xFFFFFFFF;		//Image模式，一般用于静态图的单次检测
typedef.ASF_DetectMode = typedef.UMLong;

// 人脸角度设置
typedef.ASF_OP_0_ONLY = 0x1;	// 常规预览下正方向
typedef.ASF_OP_90_ONLY = 0x2;		// 基于0°逆时针旋转90°的方向
typedef.ASF_OP_270_ONLY = 0x3;		// 基于0°逆时针旋转270°的方向
typedef.ASF_OP_180_ONLY = 0x4;		// 基于0°旋转180°的方向（逆时针、顺时针效果一样）
typedef.ASF_OP_ALL_OUT = 0x5;		// 全角度
typedef.ASF_OrientPriority = typedef.MInt32;

// 人脸角度设置
typedef.ASF_OC_0 = 0x1;			// 0 degree
typedef.ASF_OC_90 = 0x2;		// 90 degree
typedef.ASF_OC_270 = 0x3;		// 270 degree
typedef.ASF_OC_180 = 0x4;   	// 180 degree
typedef.ASF_OC_30 = 0x5;		// 30 degree
typedef.ASF_OC_60 = 0x6;		// 60 degree
typedef.ASF_OC_120 = 0x7;		// 120 degree
typedef.ASF_OC_150 = 0x8;		// 150 degree
typedef.ASF_OC_210 = 0x9;		// 210 degree
typedef.ASF_OC_240 = 0xa;		// 240 degree
typedef.ASF_OC_300 = 0xb;		// 300 degree
typedef.ASF_OC_330 = 0xc;		// 330 degree
typedef.ASF_OrientCode = typedef.MInt32;

//检测模型
typedef.ASF_DETECT_MODEL_RGB = 0x1;	//RGB图像检测模型,预留扩展其他检测模型
typedef.ASF_DetectModel = typedef.MInt32;

//人脸比对可选的模型
typedef.ASF_LIFE_PHOTO = 0x1;	//用于生活照之间的特征比对，推荐阈值0.80
typedef.ASF_ID_PHOTO = 0x2;		//用于证件照或生活照与证件照之间的特征比对，推荐阈值0.82
typedef.ASF_CompareModel = typedef.MInt32;

//版本信息
typedef.ASF_VERSION = StructType({
  Version: typedef.MPChar,   // 版本号
  BuildDate: typedef.MPChar, // 构建日期
  CopyRight: typedef.MPChar, // Copyright
});
typedef.LPASF_VERSION = ref.refType(typedef.ASF_VERSION);

//图像数据
typedef.LPASF_ImageData = typedef.LPASVLOFFSCREEN;

//单人脸信息
typedef.ASF_SingleFaceInfo = StructType({
  faceRect: typedef.MRECT,     // 人脸框信息
  faceOrient: typedef.MInt32,  // 输入图像的角度，可以参考 ArcFaceCompare_OrientCode
});
typedef.LPASF_SingleFaceInfo = ref.refType(typedef.ASF_SingleFaceInfo);

//多人脸信息
typedef.ASF_MultiFaceInfo = StructType({
  faceRect: ref.refType(typedef.MRECT),     // 人脸框信息
  faceOrient: ref.refType(typedef.MInt32),  // 输入图像的角度，可以参考 ArcFaceCompare_OrientCode
  faceNum: typedef.MInt32,     // 检测到的人脸个数
  faceID: ref.refType(typedef.MInt32)       // face ID，IMAGE模式下不返回FaceID
});
typedef.LPASF_MultiFaceInfo = ref.refType(typedef.ASF_MultiFaceInfo);

// 激活文件信息
typedef.ASF_ActiveFileInfo = StructType({
  startTime: typedef.MPChar,
  endTime: typedef.MPChar,
  platform: typedef.MPChar,
  sdkType: typedef.MPChar,
  appId: typedef.MPChar,
  sdkKey: typedef.MPChar,
  sdkVersion: typedef.MPChar,
  fileVersion: typedef.MPChar,
});
typedef.LPASF_ActiveFileInfo = ref.refType(typedef.ASF_ActiveFileInfo);

// 活体阈值设置
typedef.ASF_LivenessThreshold = StructType({
  thresholdmodel_BGR: typedef.MFloat,
  thresholdmodel_IR: typedef.MFloat,
});
typedef.LPASF_LivenessThreshold = ref.refType(typedef.ASF_LivenessThreshold);

//人脸识别相关
typedef.ASF_FaceFeature = StructType({
  feature: ref.refType(typedef.MByte), // 人脸特征信息
  featureSize: typedef.MInt32 // 人脸特征信息长度
});
typedef.LPASF_FaceFeature = ref.refType(typedef.ASF_FaceFeature);

// 年龄相关
typedef.ASF_AgeInfo = StructType({
  ageArray: ref.refType(typedef.MInt32), // "0" 代表不确定，大于0的数值代表检测出来的年龄结果
  num: typedef.MInt32                    // 检测的人脸个数
});
typedef.LPASF_AgeInfo = ref.refType(typedef.ASF_AgeInfo);


// 性别相关
typedef.ASF_GenderInfo = StructType({
  genderArray: ref.refType(typedef.MInt32), // "0" 表示 男性, "1" 表示 女性, "-1" 表示不确定
  num: typedef.MInt32                       // 检测的人脸个数
});
typedef.LPASF_GenderInfo = ref.refType(typedef.ASF_GenderInfo);

// 人脸3D 角度信息
typedef.ASF_Face3DAngle = StructType({
  roll:  ref.refType(typedef.MFloat),
  yaw:  ref.refType(typedef.MFloat),
  pitch:  ref.refType(typedef.MFloat),
  status: ref.refType(typedef.MInt32), //0: 正常，其他数值：出错
  num: typedef.MInt32,
});
typedef.LPASF_Face3DAngle = ref.refType(typedef.ASF_Face3DAngle);

// 活体信息
typedef.ASF_LivenessInfo = StructType({
  isLive: ref.refType(typedef.MInt32), // [out] 判断是否真人， 0：非真人；
  //                                      1：真人；
  //                                      -1：不确定；
  //                                      -2:传入人脸数>1；
  //                                      -3: 人脸过小
  //                                      -4: 角度过大
  //                                       5: 人脸超出边界
  num: typedef.MInt32                    // 检测的人脸个数
});
typedef.LPASF_LivenessInfo = ref.refType(typedef.ASF_LivenessInfo);


// 检测属性范围
typedef.ASF_NONE = 0x00000000;              //无属性
typedef.ASF_FACE_DETECT = 0x00000001;       //此处detect可以是tracking或者detection两个引擎之一，具体的选择由detect mode 确定
typedef.ASF_FACERECOGNITION = 0x00000004;   //人脸特征
typedef.ASF_AGE = 0x00000008;               //年龄
typedef.ASF_GENDER = 0x00000010;            //性别
typedef.ASF_FACE3DANGLE = 0x00000020;       //3D角度
typedef.ASF_LIVENESS = 0x00000080;          //RGsB活体
typedef.ASF_IR_LIVENESS = 0x00000400;       //IR活体


// js结构体
// 人脸引擎
typedef.FaceEngine = StructType({
  handle: ref.refType(typedef.MHandle)
});

// 人脸坐标
typedef.Rect = StructType({
  left: ref.types.int32,
  top: ref.types.int32,
  right: ref.types.int32,
  bottom: ref.types.int32,
});


// 多人脸信息结构体
typedef.MultiFaceInfo = StructType({
  faceRect: typedef.Rect,
  faceOrient: ArrayType('int32'),
  faceNum: ref.types.int32,
  faceId: ArrayType('int32'),
  native: typedef.LPASF_MultiFaceInfo,
});

// 活体置信度结构体
typedef.MultiFaceInfo = StructType({
  thresholdModelBGR: ref.types.float,
  thresholdModelIR: ref.types.float,
});

// 激活文件信息结构体
typedef.ActiveFileInfo = StructType({
  startTime: 'string',
  endTime: 'string',
  platform: 'string',
  sdkType: 'string',
  appId: 'string',
  sdkKey: 'string',
  sdkVersion: 'string',
  fileVersion: 'string',
});

// 版本信息结构体
typedef.Version = StructType({
  version: 'string',
  buildDate: 'string',
  copyRight: 'string',
});

// 单人脸信息结构体
typedef.Version = StructType({
  faceRect: typedef.Rect,
  faceOrient: ref.types.int32,
});

// 人脸特征结构体
typedef.FaceFeature = StructType({
  feature: ArrayType('int32'),
  featureSize: ref.types.int32,
  native: ref.refType(typedef.ASF_FaceFeature),
  featurePtr: typedef.MByte
});

// 年龄信息结构体
typedef.AgeInfo = StructType({
  ageArray: ArrayType('int32'),
  num: ref.types.int32,
});

// 性别信息结构体
typedef.GenderInfo = StructType({
  ageArray: ArrayType('int32'),
  num: ref.types.int32,
});

// 人脸3D角度信息结构体
typedef.Face3DAngle = StructType({
  roll: ArrayType('float'),
  yaw: ArrayType('float'),
  pitch: ArrayType('float'),
  status: ArrayType('int32'),
  num: ref.types.int32,
});

// 性别信息结构体
typedef.LivenessInfo = StructType({
  isLive: ArrayType('int32'),
  num: ref.types.int32,
});

/**
 * definitions
 */

typedef.ASVL_PAF_RGB16_B5G6R5 = 0x101;
typedef.ASVL_PAF_RGB16_B5G5R5 = 0x102;
typedef.ASVL_PAF_RGB16_B4G4R4 = 0x103;
typedef.ASVL_PAF_RGB16_B5G5R5T = 0x104;
typedef.ASVL_PAF_RGB16_R5G6B5 = 0x105;
typedef.ASVL_PAF_RGB16_R5G5B5 = 0x106;
typedef.ASVL_PAF_RGB16_R4G4B4 = 0x107;

typedef.ASVL_PAF_RGB24_B8G8R8 = 0x201;
typedef.ASVL_PAF_RGB24_B6G6R6 = 0x202;
typedef.ASVL_PAF_RGB24_B6G6R6T = 0x203;
typedef.ASVL_PAF_RGB24_R8G8B8 = 0x204;
typedef.ASVL_PAF_RGB24_R6G6B6 = 0x205;

typedef.ASVL_PAF_RGB32_B8G8R8 = 0x301;
typedef.ASVL_PAF_RGB32_B8G8R8A8 = 0x302;
typedef.ASVL_PAF_RGB32_R8G8B8 = 0x303;
typedef.ASVL_PAF_RGB32_A8R8G8B8 = 0x304;
typedef.ASVL_PAF_RGB32_R8G8B8A8 = 0x305;

typedef.ASVL_PAF_YUV = 0x401;
typedef.ASVL_PAF_YVU = 0x402;
typedef.ASVL_PAF_UVY = 0x403;
typedef.ASVL_PAF_VUY = 0x404;
typedef.ASVL_PAF_YUYV = 0x501;
typedef.ASVL_PAF_YVYU = 0x502;
typedef.ASVL_PAF_UYVY = 0x503;
typedef.ASVL_PAF_VYUY = 0x504;
typedef.ASVL_PAF_YUYV2 = 0x505;
typedef.ASVL_PAF_YVYU2 = 0x506;
typedef.ASVL_PAF_UYVY2 = 0x507;
typedef.ASVL_PAF_VYUY2 = 0x508;
typedef.ASVL_PAF_YYUV = 0x509;
typedef.ASVL_PAF_I420 = 0x601;
typedef.ASVL_PAF_I422V = 0x602;
typedef.ASVL_PAF_I422H = 0x603;
typedef.ASVL_PAF_I444 = 0x604;
typedef.ASVL_PAF_YV12 = 0x605;
typedef.ASVL_PAF_YV16V = 0x606;
typedef.ASVL_PAF_YV16H = 0x607;
typedef.ASVL_PAF_YV24 = 0x608;
typedef.ASVL_PAF_GRAY = 0x701;
typedef.ASVL_PAF_NV12 = 0x801;
typedef.ASVL_PAF_NV21 = 0x802;
typedef.ASVL_PAF_LPI422H = 0x803;
typedef.ASVL_PAF_LPI422H2 = 0x804;
typedef.ASVL_PAF_NV41 = 0x805;
typedef.ASVL_PAF_NEG_UYVY = 0x901;
typedef.ASVL_PAF_NEG_I420 = 0x902;
typedef.ASVL_PAF_MONO_UYVY = 0xa01;
typedef.ASVL_PAF_MONO_I420 = 0xa02;
typedef.ASVL_PAF_P8_YUYV = 0xb03;
typedef.ASVL_PAF_SP16UNIT = 0xc01;
typedef.ASVL_PAF_DEPTH_U16 = 0xc02;
typedef.ASVL_PAF_RAW10_RGGB_10B = 0xd01;
typedef.ASVL_PAF_RAW10_GRBG_10B = 0xd02;
typedef.ASVL_PAF_RAW10_GBRG_10B = 0xd03;
typedef.ASVL_PAF_RAW10_BGGR_10B = 0xd04;
typedef.ASVL_PAF_RAW12_RGGB_12B = 0xd05;
typedef.ASVL_PAF_RAW12_GRBG_12B = 0xd06;
typedef.ASVL_PAF_RAW12_GBRG_12B = 0xd07;
typedef.ASVL_PAF_RAW12_BGGR_12B = 0xd08;
typedef.ASVL_PAF_RAW10_RGGB_16B = 0xd09;
typedef.ASVL_PAF_RAW10_GRBG_16B = 0xd0A;
typedef.ASVL_PAF_RAW10_GBRG_16B = 0xd0B;
typedef.ASVL_PAF_RAW10_BGGR_16B = 0xd0C;
typedef.ASVL_PAF_RAW10_GRAY_10B = 0xe01;
typedef.ASVL_PAF_RAW10_GRAY_16B = 0xe81;

